home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Pascal / Snippets / PNL Libraries / MyOOMainLoop.p < prev    next >
Encoding:
Text File  |  1997-06-04  |  45.2 KB  |  1,718 lines  |  [TEXT/CWIE]

  1. unit MyOOMainLoop;
  2.  
  3. interface
  4.  
  5.     uses
  6.         Types, Menus, Quickdraw, QuickdrawText, Events, Windows, Dialogs, AppleEvents, Drag,
  7.         MyFMenus;
  8.  
  9.     const
  10.         WT_NotMine = 'NtMe';
  11.         WT_Generic = 'Genr';
  12.         bad_window_id = -1;
  13.         kAECloseAll = 'Clos';
  14.  
  15.     type
  16.         SCType = (SCSave, SCCancel, SCDiscard);
  17.         WObject = object
  18.                 window: DialogPtr;
  19.                 resid: integer;
  20.                 window_type: OSType;
  21.                 window_id: longint;
  22.                 growRect: Rect; { minimum/maximum Rect size (for use with grow window) }
  23.                 zoomSize: Point; { Optimum zoom size }
  24.                 zoomed: boolean;
  25.                 unzoomed: Rect;
  26.                 draw_grow_icon: boolean;
  27.                 is_active: boolean;
  28.                 is_default_object: boolean;
  29.                 close_hides_window: boolean;
  30.                 popup_title_menu: MenuHandle;
  31.                 AppleGuideWindowType: Str31;
  32.                 onlyone: ^WObject;    { Set onlyone^ to nil when we destroy ourselves }
  33.                 timetoclose:boolean;
  34.                 { private TrackingHandler variables }
  35.                 th_can_accept_drag: boolean;
  36.                 th_drag_hilited: boolean;
  37.                 th_drag_hilite_visible: boolean;
  38.                 th_ever_left_original_hilite_region: boolean;
  39.                 th_drag_hilite_rgn: RgnHandle;
  40.                 th_drag_original_hilite_rgn: RgnHandle;
  41.                 th_drag_invert_rgn: RgnHandle;
  42.                 procedure JointCreate (id: integer);
  43.                 procedure Create (id: integer);
  44.                 procedure CreateBehind (id: integer; behind: WindowPtr);
  45.                 procedure Destroy;
  46.                 procedure GetWindowPos (h: Handle);
  47.                 procedure SetWindowPos (h: Handle; var wasvisible: boolean);
  48.                 function SaveChangesID (alert_id: integer): integer;
  49.                 function SaveChanges: SCType;
  50.                 procedure DoClose;
  51. { DoClose checks modified things etc, then calls Destroy }
  52.                 function SetMenuBar: boolean;
  53.                 procedure SetMenus;
  54.                 function EditMenuEnabled: boolean;
  55.                 procedure SetEditMenuItem (item: integer);
  56.                 procedure DoEditMenu (item: integer);
  57.                 function GetAESelection (var reply: AppleEvent): OSErr;
  58.                 function GetAEWindow (var windowrec: AERecord): OSErr;
  59.                 function DoMenuKey (const er: EventRecord; ch: char): longint;
  60.                 procedure CalculateRegion (var rgn: RgnHandle);
  61.                 function WaitForEvent (var er: EventRecord; sleep: longint): boolean;
  62.                 procedure DoIdle;
  63.                 procedure DoIdleAlways;
  64.                 procedure DoDiskEvent (message: longint);
  65.                 procedure DoSuspendResume (resume: boolean);
  66.                 procedure DoHighLevel (const er: EventRecord);
  67.                 procedure DoContent (const er: EventRecord);
  68.                 procedure DoKey (const er:EventRecord; ch: char);
  69.                 procedure DoSpecialKey (const er:EventRecord; ch: char);
  70.                 procedure DoAutoKey (const er:EventRecord; ch: char);
  71.                 procedure DoPopupTitle (choice: integer);
  72.                 function CheckPopupTitle (where: Point): boolean;
  73.                 procedure DoDrag (where: Point);
  74.                 procedure DoGrow (where: Point);
  75.                 procedure Zoom (zoomout: boolean; fullscreen: boolean);
  76.                 procedure DoZoom (where: Point; code: integer);
  77.                 procedure DoGoAway (where: Point);
  78.                 procedure DoUpdate;
  79.                 procedure DoMouseMoved (where: Point);
  80.                 procedure DrawGrow;
  81.                 procedure DoActivateDeactivate (activate: boolean);
  82.                 procedure TextChanged; { called for paste/clear/cut/key down etc }
  83.                 procedure Resize;
  84.                 procedure InitialZoom (h, v: integer);
  85.                 procedure Draw;
  86.                 procedure TrackingRemoveHiliting(dragref: DragReference); { must be idenpotent }
  87.                 function TrackingHandler (message: DragTrackingMessage; dragref: DragReference): OSErr;
  88.                 function MyTrackingEnterWindow( dragref: DragReference ): Boolean;
  89.                 procedure MyTrackingLeaveWindow( dragref: DragReference );
  90.                 procedure MyTrackingInWindow( dragref: DragReference; localwhere: Point; var new_drag_hilited: Boolean; new_drag_hilite_rgn, new_drag_invert_rgn: RgnHandle );
  91.                 function ReceiveHandler (dragref: DragReference): OSErr;
  92.                 function DragSend (flavor: FlavorType; item: ItemReference; dragref: DragReference): OSErr;
  93.                 function DoSetupDrag (dragref: DragReference; dragrgn: RgnHandle): OSErr;
  94.                 procedure DoTrackDrag (const er: EventRecord);
  95.                 function DoMainClick (const er: EventRecord; wp: WindowPtr; code: integer): boolean;
  96.                 function DoIsDialogEvent (const er: EventRecord): boolean;
  97.                 function DoDialogSelect (const er: EventRecord; var dlg: DialogPtr; var item: integer): boolean;
  98.                 function HandleSimpleEvents (var er: EventRecord): boolean;
  99.                 function HandleEvents (var er: EventRecord): boolean;
  100.             end;
  101.         DObject = object(WObject)
  102.                 ok_item, cancel_item, outline_item: integer;
  103.                 handle_shift_tab: boolean;
  104.                 disable_edit_menu: boolean;
  105.                 text_return: boolean;
  106.                 support_edittext_draging_send: Boolean;
  107.                 support_edittext_draging_receive: Boolean;
  108.                 procedure Create (id: integer);
  109.                 override;
  110.                 procedure CreateBehind (id: integer; behind: WindowPtr);
  111.                 override;
  112.                 procedure Destroy;
  113.                 override;
  114.                 procedure SetOOOutline (def_item, user_item: integer);
  115.                 procedure DrawOutline( foreground: boolean );
  116.                 procedure DrawUserItem( item: integer );
  117.                 procedure HandleUserItem( item: integer );
  118.                 procedure HandleAllUserItems;
  119.                 procedure DoActivateDeactivate (activate: boolean);
  120.                 override;
  121.                 function HandleEvents (var er: EventRecord): boolean;
  122.                 override;
  123.                 procedure DoItem (item: integer);
  124.                 procedure DoItemWhere (const er: EventRecord; item: integer);
  125.                 procedure DoCancel (const er:EventRecord; ch: char);
  126.                 procedure DoOK (const er:EventRecord; ch: char);
  127.                 procedure DoDialogCut;
  128.                 procedure DoDialogCopy;
  129.                 procedure DoDialogPaste;
  130.                 procedure DoDialogDelete;
  131.                 procedure SetEditMenuItem (item: integer);
  132.                 override;
  133.                 function EditMenuEnabled: boolean;
  134.                 override;
  135.                 procedure DoEditMenu (item: integer);
  136.                 override;
  137.                 function DoIsDialogEvent (const er: EventRecord): boolean;
  138.                 override;
  139.                 function GetAESelection (var reply: AppleEvent): OSErr;
  140.                 override;
  141.                 procedure CalculateRegion (var rgn: RgnHandle);
  142.                 override;
  143.                 procedure InsertTextAndSelect( field: integer; offset: integer; data: Str255 );
  144.                 function MyTrackingEnterWindow( dragref: DragReference ): Boolean;
  145.                 override;
  146.                 procedure MyTrackingLeaveWindow( dragref: DragReference );
  147.                 override;
  148.                 procedure MyTrackingInWindow( dragref: DragReference; localwhere: Point; var new_drag_hilited: Boolean; new_drag_hilite_rgn, new_drag_invert_rgn: RgnHandle );
  149.                 override;
  150.                 function ReceiveHandler(dragref: DragReference): OSErr;
  151.                 override;
  152.             end;
  153.  
  154.     var
  155.         default_object: WObject;
  156.         edit_menu_always_enabled: boolean;
  157.         last_event_time: longint;
  158.         last_event: EventRecord;
  159.         last_event_had_option: boolean;
  160.         last_event_had_command: boolean;
  161.         last_event_had_shift: boolean;
  162.         last_event_had_control: boolean;
  163.         has_DragManager: boolean;
  164.  
  165.     procedure StartupMainLoop;
  166.     procedure ConfigureMainLoop (dobj: DObject);
  167. { dobj will be used returned with window set to wp whenever GetWObject/GetDObject is called with a DA or nil window }
  168.     function GetWType (wp: WindowPtr): OSType;
  169.     function GetWObject (wp: WindowPtr): WObject;
  170.     function GetDObject (dlg: DialogPtr): DObject;
  171.     function FrontObject: WObject;
  172.     function IsWObjectFront (o: WObject): boolean;
  173.     function FindWindowID (id: longint): WObject;
  174.     procedure DoCloseAll (all: boolean);
  175. {    procedure CallIdleAlways;}
  176.  
  177. implementation
  178.  
  179.     uses
  180.         Memory, ToolUtils, Scrap, Fonts, Resources, Errors, DiskInit, AEObjects, AERegistry, 
  181.         OSUtils, EPPC, TextEdit, 
  182.         CodeFragments, Drag, Script, Processes, GestaltEqu, MixedMode, MyStartup, MyStrings, MyAssertions, 
  183.         MyMenus, MyTypes, MyFMenus, BaseGlobals, MySystemGlobals, MyCursors,MyCallProc, MyEvents,
  184.         MyCleverAlerts, MyTEUtils, MyAssertions, MyDialogs, MyAEUtils, MyWindows, MyMathUtils, 
  185.         MyDrag, MyLowLevel, MyUtils, MyTextEdit, MyRegions, MyMemory, MyStrings;
  186.  
  187.     const
  188.         titlebar_hight = 18;
  189.  
  190.     const
  191. { from EPPC }
  192.         OOMagic = 'MyOO';
  193.         BadOOMagic = 'bado';
  194.  
  195.     type
  196.         myWindowRecord = record
  197.                 thewindow: WindowRecord;
  198.                 magic: OSType;
  199.             end;
  200.         myWindowPtr = ^myWindowRecord;
  201.         myDialogRecord = record
  202.                 thedialog: DialogRecord;
  203.                 magic: OSType;
  204.             end;
  205.         myDialogPtr = ^myDialogRecord;
  206.  
  207. {$ifc do_debug}
  208.     var
  209.         startup_check: integer;
  210. {$endc}
  211.  
  212.     var
  213.         last_window_id: longint;
  214.         gMyDragSendProc : UniversalProcPtr;
  215.         dDrawUserItemProc: UniversalProcPtr;
  216.  
  217.     procedure DoCloses (all: boolean);
  218.         var
  219.             fw: WindowPtr;
  220.     begin
  221.         if all then begin
  222.             fw := FrontWindow;
  223.             while fw <> nil do begin
  224.                 FrontObject.DoClose;
  225.                 if fw = FrontWindow then begin
  226.                     leave;
  227.                 end;
  228.                 fw := FrontWindow;
  229.             end;
  230.         end else begin
  231.             FrontObject.DoClose;
  232.         end;
  233.     end;
  234.  
  235.     function HandleClose (var event, reply: AppleEvent; refcon: longint): OSErr;
  236.         var
  237.             err: OSErr;
  238.     begin
  239. {$unused(event, reply)}
  240.         if FrontWindow <> nil then begin
  241.             DoCloses(refcon <> 0);
  242.             err := noErr;
  243.         end else begin
  244.             err := errAENoSuchObject;
  245.         end;
  246.         HandleClose := err;
  247.     end;
  248.  
  249.     procedure DoCloseAll (all: boolean);
  250.     begin
  251.         if has_AppleEvents then begin
  252.             if all then begin
  253.                 SendSelfSimpleEvent(kAECoreSuite, kAECloseAll);
  254.             end else begin
  255.                 SendSelfSimpleEvent(kAECoreSuite, kAEClose);
  256.             end;
  257.         end else begin
  258.             DoCloses(all);
  259.         end;
  260.     end;
  261.  
  262.     function GetWRC (wp: WindowPtr): WObject;
  263.         var
  264.             rc: longint;
  265.     begin
  266.         rc := 0;
  267.         if (wp <> nil) & WindowInWindowList(wp) & (WindowPeek(wp)^.windowKind >= 0) then begin
  268.             if ((WindowPeek(wp)^.windowKind = dialogKind) & (myDialogPtr(wp)^.magic = OOMagic)) | (myWindowPtr(wp)^.magic = OOMagic) then begin
  269.                 rc := GetWRefCon(wp);
  270.             end;
  271.         end;
  272.         if rc = 0 then begin
  273.             default_object.window := wp;
  274.             rc := longint(default_object);
  275.         end;
  276.         GetWRC := WObject(rc);
  277.     end;
  278.  
  279.     function GetWType (wp: WindowPtr): OSType;
  280.         var
  281.             wo: WObject;
  282.     begin
  283.         wo := GetWRC(wp);
  284.         if wo.is_default_object then begin
  285.             GetWType := WT_NotMine;
  286.         end else begin
  287.             GetWType := wo.window_type;
  288.         end;
  289.     end;
  290.  
  291.     function GetWObject (wp: WindowPtr): WObject;
  292.     begin
  293.         GetWObject := GetWRC(wp);
  294.     end;
  295.  
  296.     function FindWindowID (id: longint): WObject;
  297.         const
  298.             WindowList = $9D6;
  299.         type
  300.             WindowPtrPtr = ^WindowPtr;
  301.         var
  302.             w: WindowPtr;
  303.             wo: WObject;
  304.     begin
  305.         FindWindowID := nil;
  306.         if id <> bad_window_id then begin
  307.             w := WindowPtrPtr(WindowList)^;
  308.             while w <> nil do begin
  309.                 wo := GetWObject(w);
  310.                 if (not wo.is_default_object) & (wo.window_id = id) then begin
  311.                     FindWindowID := wo;
  312.                     leave;
  313.                 end;
  314.                 w := WindowPtr(WindowPeek(w)^.nextWindow);
  315.             end;
  316.         end;
  317.     end;
  318.  
  319.     function GetDObject (dlg: DialogPtr): DObject;
  320.     begin
  321.         GetDObject := DObject(GetWRC(dlg));
  322.     end;
  323.  
  324.     function FrontObject: WObject;
  325.     begin
  326.         FrontObject := GetWRC(FrontWindow);
  327.     end;
  328.  
  329.     function IsWObjectFront (o: WObject): boolean;
  330.     begin
  331.         if o = nil then begin
  332.             IsWObjectFront := false;
  333.         end else if o.window = nil then begin
  334.             IsWObjectFront := false;
  335.         end else begin
  336.             IsWObjectFront := o.window = FrontWindow;
  337.         end;
  338.     end;
  339.  
  340.     function WObject.MyTrackingEnterWindow( dragref: DragReference ): Boolean;
  341.     begin
  342. {$unused(dragref)}
  343.         MyTrackingEnterWindow := false;
  344.     end;
  345.     
  346.     procedure WObject.MyTrackingLeaveWindow( dragref: DragReference );
  347.     begin
  348. {$unused(dragref)}
  349.     end;
  350.  
  351.     procedure WObject.MyTrackingInWindow( dragref: DragReference; localwhere: Point; var new_drag_hilited: Boolean; new_drag_hilite_rgn, new_drag_invert_rgn: RgnHandle );
  352.     begin
  353. {$unused(dragref, localwhere, new_drag_hilited, new_drag_hilite_rgn, new_drag_invert_rgn)}
  354.         new_drag_hilited := false;
  355.     end;
  356.  
  357.     procedure WObject.TrackingRemoveHiliting( dragref: DragReference ); { must be idenpotent }
  358.         var
  359.             junk: OSErr;
  360.     begin
  361.         if th_drag_hilite_visible then begin
  362.             junk := HideDragHilite( dragref );
  363.             th_drag_hilite_visible := false;
  364.         end;
  365.         if th_drag_hilited then begin
  366.             InvertRgn( th_drag_invert_rgn );
  367.             MakeRegionEmpty( th_drag_invert_rgn );
  368.             th_drag_hilited := false;
  369.         end;
  370.     end;
  371.     
  372.     function WObject.TrackingHandler (message: DragTrackingMessage; dragref: DragReference): OSErr;
  373.         var
  374.             mouse, pinnedmouse: Point;
  375.             attributes: DragAttributes;
  376.             new_drag_hilited, new_drag_hilite_visible: boolean;
  377.             new_drag_hilite_rgn, new_drag_invert_rgn: RgnHandle;
  378.             err: OSErr;
  379.             has_left_sender_window, in_sender_window: Boolean;
  380.     begin
  381.         SetPort(window);
  382.         err := GetDragAttributes(dragref, attributes);
  383.         in_sender_window := (band(attributes, dragInsideSenderWindow) <> 0);
  384.         has_left_sender_window := (band(attributes, dragHasLeftSenderWindow) <> 0);
  385.         if err = noErr then begin
  386.             case message of
  387.                 dragTrackingEnterHandler, dragTrackingLeaveHandler: 
  388.                     ;  { WE DONT GET THESE! }
  389.                 dragTrackingEnterWindow:  begin
  390.                     th_drag_hilited := false;
  391.                     th_drag_hilite_visible := false;
  392.                     th_drag_hilite_rgn := NewRgn;
  393.                     th_drag_invert_rgn := NewRgn;
  394.                     th_drag_original_hilite_rgn := NewRgn;
  395.                     th_can_accept_drag := MyTrackingEnterWindow( dragref );
  396.                     if in_sender_window & (GetDragOrigin( dragref, mouse ) = noErr) then begin
  397. {DebugStr( 'In Sender, got origin' );}
  398.                         GlobalToLocal( mouse );
  399.                         MyTrackingInWindow( dragref, mouse, new_drag_hilited, th_drag_original_hilite_rgn, th_drag_invert_rgn );
  400.                         SetEmptyRgn( th_drag_invert_rgn );
  401.                         if not new_drag_hilited then begin
  402.                             SetEmptyRgn( th_drag_original_hilite_rgn );
  403.                         end;
  404.                     end;
  405.                     th_ever_left_original_hilite_region := EmptyRgn( th_drag_original_hilite_rgn );
  406.                 end;
  407.                 dragTrackingInWindow:  begin
  408.                     if th_can_accept_drag then begin
  409.                         err := GetDragMouse(dragref, mouse, pinnedmouse);
  410.                         GlobalToLocal(mouse);
  411.                         
  412.                         if not th_ever_left_original_hilite_region then begin
  413.                             th_ever_left_original_hilite_region := has_left_sender_window | not PtInRgn( mouse, th_drag_original_hilite_rgn );
  414.                         end;
  415.                         
  416.                         new_drag_hilite_rgn := NewRgn;
  417.                         new_drag_invert_rgn := NewRgn;
  418.                         MyTrackingInWindow( dragref, mouse, new_drag_hilited, new_drag_hilite_rgn, new_drag_invert_rgn );
  419.                         new_drag_hilite_visible := new_drag_hilited and th_ever_left_original_hilite_region;
  420.                         if not new_drag_hilited then begin
  421.                             SetEmptyRgn( new_drag_invert_rgn );
  422.                         end;
  423.                         if not new_drag_hilite_visible then begin
  424.                             SetEmptyRgn( new_drag_hilite_rgn );
  425.                         end;
  426.                         
  427.                         { update the hilite region }
  428.                         if (new_drag_hilite_visible <> th_drag_hilite_visible) | not EqualRgn( new_drag_hilite_rgn, th_drag_hilite_rgn ) then begin
  429.                             if th_drag_hilite_visible then begin
  430.                                 err := HideDragHilite(dragref);
  431.                             end;
  432.                             if new_drag_hilite_visible then begin
  433.                                 err := ShowDragHilite(dragref, new_drag_hilite_rgn, true);
  434.                             end;
  435.                             DisposeRgn( th_drag_hilite_rgn );
  436.                             th_drag_hilite_rgn := new_drag_hilite_rgn;
  437.                         end else begin
  438.                             DisposeRgn( new_drag_hilite_rgn );
  439.                         end;
  440.  
  441.                         { update the invert region }
  442.                         if not EqualRgn( new_drag_invert_rgn, th_drag_invert_rgn ) then begin
  443.                             XorRgn( new_drag_invert_rgn, th_drag_invert_rgn, new_drag_invert_rgn ); { invert them both }
  444.                             InvertRgn( new_drag_invert_rgn );
  445.                             XorRgn( new_drag_invert_rgn, th_drag_invert_rgn, new_drag_invert_rgn ); { remove old }
  446.                             DisposeRgn( th_drag_invert_rgn );
  447.                             th_drag_invert_rgn := new_drag_invert_rgn;
  448.                         end else begin
  449.                             DisposeRgn( new_drag_invert_rgn );
  450.                         end;
  451.                         
  452.                         th_drag_hilited := new_drag_hilited;                        
  453.                         th_drag_hilite_visible := new_drag_hilite_visible;                        
  454.                     end;
  455.                 end;
  456.                 dragTrackingLeaveWindow:  begin
  457.                     TrackingRemoveHiliting( dragref );
  458.                     MyTrackingLeaveWindow( dragref );
  459.                     th_can_accept_drag := false;
  460.                     DisposeRgn( th_drag_hilite_rgn );
  461.                     DisposeRgn( th_drag_invert_rgn );
  462.                     DisposeRgn( th_drag_original_hilite_rgn );
  463.                 end;
  464.                 otherwise begin
  465.                     { do nothing }
  466.                 end;
  467.             end;
  468.         end;
  469.         TrackingHandler := err;
  470.     end;
  471.  
  472.     function MyTrackingHandler (message: DragTrackingMessage; window: WindowPtr; refcon: Ptr; dragref: DragReference): OSErr;
  473.     begin
  474. {$unused(refcon)}
  475.         MyTrackingHandler := GetWObject(window).TrackingHandler(message, dragref);
  476.     end;
  477.  
  478.     function WObject.ReceiveHandler (dragref: DragReference): OSErr;
  479.     begin
  480. {$unused(dragref)}
  481.         ReceiveHandler := -1;
  482.     end;
  483.  
  484.     function MyReceiveHandler (window: WindowPtr; refcon: Ptr; dragref: DragReference): OSErr;
  485.     begin
  486. {$unused(refcon)}
  487.         MyReceiveHandler := GetWObject(window).ReceiveHandler(dragref);
  488.     end;
  489.  
  490.     function WObject.DragSend (flavor: FlavorType; item: ItemReference; dragref: DragReference): OSErr;
  491.     begin
  492. {$unused(flavor, item, dragref)}
  493.         DragSend := -1;
  494.     end;
  495.  
  496.     var
  497.         drag_obj: WObject;
  498.  
  499.     function MyDragSend (flavor: FlavorType; refcon: Ptr; item: ItemReference; dragref: DragReference): OSErr;
  500.     begin
  501. {$unused(refcon)}
  502.         MyDragSend := drag_obj.DragSend(flavor, item, dragref);
  503.     end;
  504.  
  505.     function WObject.DoSetupDrag (dragref: DragReference; dragrgn: RgnHandle): OSErr;
  506.     begin
  507. {$unused(dragref, dragrgn)}
  508.         DoSetupDrag := -1;
  509.     end;
  510.  
  511.     procedure WObject.DoTrackDrag (const er: EventRecord);
  512.         var
  513.             err: OSErr;
  514.             dragref: DragReference;
  515.             dragrgn: RgnHandle;
  516.     begin
  517.         drag_obj := self;
  518.         err := NewDrag(dragref);
  519.         if err = noErr then begin
  520.             dragrgn := NewRgn;
  521.             err := MemError;
  522.             if err = noErr then begin
  523.                 err := DoSetupDrag(dragref, dragrgn);
  524.                 if err = noErr then begin
  525.                     err := SetDragSendProc(dragref, gMyDragSendProc, nil);
  526.                 end;
  527.                 if err = noErr then begin
  528.                     CursorSetProcessing(false);
  529.                     err := TrackDrag(dragref, er, dragrgn);
  530.                 end;
  531.                 DisposeRgn(dragrgn);
  532.             end;
  533.             err := DisposeDrag(dragref);
  534.         end;
  535.     end;
  536.  
  537.     function WObject.SaveChangesID (alert_id: integer): integer;
  538.         var
  539.             a: integer;
  540.             title, ing: Str255;
  541.     begin
  542.         SelectWindow(window);
  543.         GetWTitle(window, title);
  544.         if quitNow then begin
  545.             ing := GetGlobalStr( GS_Quiting );
  546.         end else begin
  547.             ing := GetGlobalStr( GS_Closing );
  548.         end;
  549.         CleverParamText(title, ing, '', '');
  550.         a := CleverAlert(alert_id);
  551.         SaveChangesID := a;
  552.     end;
  553.  
  554.     function WObject.SaveChanges: SCType;
  555.     begin
  556.         SaveChanges := SCType(SaveChangesID(save_changes_alert_id) - 1);
  557.     end;
  558.  
  559.     function WObject.EditMenuEnabled: boolean;
  560.     begin
  561.         if window = nil then begin
  562.             EditMenuEnabled := false;
  563.         end else begin
  564.             EditMenuEnabled := WindowPeek(window)^.windowKind < 0;
  565.         end;
  566.     end;
  567.  
  568.     function WObject.SetMenuBar: boolean;
  569.         var
  570.             oldEditEnabled, editEnabled: boolean;
  571.     begin
  572.         oldEditEnabled := GetIDItemEnable(M_Edit, 0);
  573.         editEnabled := FrontObject.EditMenuEnabled or edit_menu_always_enabled;
  574.         if editEnabled <> oldEditEnabled then begin
  575.             SetIDItemEnable(M_Edit, 0, editEnabled);
  576.         end;
  577.         SetMenuBar := editEnabled <> oldEditEnabled;
  578.     end;
  579.  
  580.     procedure WObject.SetMenus;
  581.     begin
  582.         SetFMenus;
  583.     end;
  584.  
  585.     procedure WObject.SetEditMenuItem (item: integer);
  586.     begin
  587.         if not EditMenuEnabled then begin
  588.             SetIDItemEnable(M_Edit, item, false);
  589.         end;
  590.     end;
  591.  
  592.     procedure WObject.DoEditMenu (item: integer);
  593.         var
  594.             dummyb: boolean;
  595.     begin
  596.         if item <= 6 then begin
  597.             dummyb := SystemEdit(item - 1);
  598.         end;
  599.     end;
  600.  
  601.     function WObject.GetAESelection (var reply: AppleEvent): OSErr;
  602.     begin
  603. {$unused(reply)}
  604.         GetAESelection := errAENoUserSelection;
  605.     end;
  606.  
  607.     function WObject.GetAEWindow (var windowrec: AERecord): OSErr;
  608.         var
  609.             err, junk: OSErr;
  610.             s: Str255;
  611.             r: Rect;
  612.     begin
  613.         AECreate(windowrec);
  614.         if is_default_object then begin
  615.             err := errAEDescNotFound;
  616.         end else begin
  617.             err := AECreateList(nil, 0, true, windowrec);
  618.             GetWTitle(window, s);
  619.             if err = noErr then begin
  620.                 junk := PutStringToAERecord(windowrec, pName, s);
  621.                 r := window^.portRect;
  622.                 SetPort(window);
  623.                 LocalToGlobal(r.topLeft);
  624.                 LocalToGlobal(r.botRight);
  625.                 junk := AEPutParamPtr(windowrec, keyAEBounds, typeQDRectangle, @r, SizeOf(r));
  626.                 junk := AEPutParamPtr(windowrec, keyAEPosition, typeQDPoint, @r.topLeft, SizeOf(r.topLeft));
  627.             end;
  628.         end;
  629.         GetAEWindow := err;
  630.     end;
  631.  
  632.     function WObject.DoMenuKey (const er: EventRecord; ch: char): longint;
  633.     begin
  634. {$unused(ch)}
  635.         DoMenuKey := DoFMenuKey(er);
  636.     end;
  637.  
  638.     procedure WObject.CalculateRegion (var rgn: RgnHandle);
  639.     begin
  640.         CursorSetArrow;
  641.         rgn := nil;
  642.     end;
  643.  
  644.     function WObject.WaitForEvent (var er: EventRecord; sleep: longint): boolean;
  645.         var
  646.             rgn: RgnHandle;
  647.     begin
  648.         rgn := nil;
  649.         if (window = nil) | (GetWType(window) = WT_NotMine) | IsWindowShaded(window) then begin
  650.             CursorSetArrow;
  651.         end else begin
  652.             CalculateRegion(rgn);
  653.         end;
  654.         CursorSetProcessing(false);
  655.         WaitForEvent := WaitNextEvent(everyEvent, er, sleep, rgn);
  656.         if rgn <> nil then begin
  657.             DisposeRgn(rgn);
  658.         end;
  659.     end;
  660.  
  661.     procedure WObject.DoDiskEvent (message: longint);
  662.         var
  663.             pt: Point;
  664.             oe: OSErr;
  665.     begin
  666.         if (HiWord(message) <> noErr) then begin
  667.             with GetQDGlobals^.screenBits.bounds do begin
  668.                 pt.h := (right - left - 304) div 2;
  669.                 pt.v := (bottom - top - 156) div 3;
  670.             end;
  671.             CursorSetArrow;
  672.             CursorSetProcessing(false);
  673.             oe := DIBadMount(pt, message);
  674.         end;
  675.     end;
  676.  
  677.     procedure WObject.DoSuspendResume (resume: boolean);
  678.     begin
  679.         SetInForeground(resume);
  680.         if FrontWindow <> nil then begin
  681.             FrontObject.DoActivateDeactivate(resume);
  682.         end;
  683.         CursorSetArrow;
  684.     end;
  685.  
  686.     procedure WObject.DoHighLevel (const er: EventRecord);
  687.         var
  688.             oe: OSErr;
  689.     begin
  690.         if has_AppleEvents then begin
  691.             oe := AEProcessAppleEvent(er);
  692.         end;
  693.     end;
  694.  
  695.     procedure WObject.JointCreate (id: integer); { Called for DefaultObject too! }
  696.     begin
  697.         AssertDidStartup( startup_check );
  698.         HLockHi(Handle(self));
  699.         popup_title_menu := nil;
  700.         AppleGuideWindowType := '';
  701.         if window <> nil then begin
  702.             SetWRefCon(window, ord4(self));
  703.             GetWindowRect(window, unzoomed);
  704.         end;
  705.         zoomed := false;
  706.         close_hides_window := false;
  707.         SetRect(growRect, 63, 61, 25000, 25000);
  708.         zoomSize.h := 30000;
  709.         zoomSize.v := 30000;
  710.         window_type := WT_Generic;
  711.         draw_grow_icon := false;
  712.         window_id := last_window_id;
  713.         last_window_id := last_window_id + 1;
  714.         resid := id;
  715.         is_default_object := false;
  716.         onlyone := nil;
  717.         timetoclose:=false;
  718.     end;
  719.  
  720.     procedure WObject.CreateBehind (id: integer; behind: WindowPtr);
  721.         var
  722.             wp: myWindowPtr;
  723.             junk: OSErr;
  724.     begin
  725.         junk := MNewPtr( wp, SizeOf(myWindowRecord) );
  726.         wp^.magic := OOMagic;
  727.         if GetResource( 'wctb', id ) <> nil then begin
  728.             window := GetNewCWindow(id, Ptr(wp), behind);
  729.         end else begin
  730.             window := GetNewWindow(id, Ptr(wp), behind);
  731.         end;
  732.         Assert( window <> nil );
  733.         JointCreate(id);
  734.     end;
  735.  
  736.     procedure WObject.Create (id: integer);
  737.     begin
  738.         CreateBehind(id, window_at_front);
  739.     end;
  740.  
  741.     procedure WObject.Destroy;
  742.     begin
  743.         if (window <> nil) & (GetWType(window) <> WT_NotMine) then begin
  744.             myWindowPtr(window)^.magic := BadOOMagic;
  745.             DisposeWindow(window);
  746.             if onlyone <> nil then begin
  747.                 onlyone^ := nil;
  748.             end;
  749.             dispose(self);
  750.         end;
  751.     end;
  752.  
  753. {$PUSH}
  754. {$ALIGN MAC68K}
  755.  
  756.     type
  757.         savedWindowRecord = record
  758.                 windowpos: Rect; { the window position }
  759.                 windowvis: Rect; { the visible part of the title bar }
  760.                 zoomed: boolean;
  761.                 visible: boolean;
  762.             end;
  763.         savedWindowPtr = ^savedWindowRecord;
  764.         savedWindowHandle = ^savedWindowPtr;
  765.         
  766. {$ALIGN RESET}
  767. {$POP}
  768.  
  769.     procedure WObject.GetWindowPos (h: Handle);
  770.         var
  771.             rgn: RgnHandle;
  772.             r1, r2, global_portrect: Rect;
  773.     begin
  774.         HUnlock(h);
  775.         SetHandleSize(h, SizeOf(savedWindowRecord));
  776.         HLock(h);
  777.         with savedWindowHandle(h)^^ do begin
  778.             SetPort(window);
  779.             visible := WindowPeek(window)^.visible;
  780.             GetWindowPortRect(window, global_portrect);
  781.             LocalToGlobal(global_portrect.topLeft);
  782.             LocalToGlobal(global_portrect.botRight);
  783.             windowpos := global_portrect;
  784.             windowpos.top := windowpos.top - titlebar_hight; { title bar }
  785.             rgn := NewRgn;
  786.             RectRgn(rgn, windowpos);
  787.             SectRgn(GetGrayRgn, rgn, rgn);
  788.             windowvis := rgn^^.rgnBBox;
  789.             DisposeRgn(rgn);
  790.             r1 := global_portrect;
  791.             GetWindowStandardState(window, r2);
  792.             InsetRect(r1, -7, -7);
  793.             zoomed := PtInRect(r2.topLeft, r1) and PtInRect(r2.botRight, r1);
  794.         end;
  795.         HUnlock(h);
  796.     end;
  797.  
  798.     procedure WObject.SetWindowPos (h: Handle; var wasvisible: boolean);
  799.         var
  800.             rgn: RgnHandle;
  801.             r: Rect;
  802.             dummy: boolean;
  803.     begin
  804.         if (h <> nil) & (GetHandleSize(h) = SizeOf(savedWindowRecord)) then begin
  805.             HLock(h);
  806.             with savedWindowHandle(h)^^ do begin
  807.                 wasvisible := visible;
  808.                 rgn := NewRgn;
  809.                 RectRgn(rgn, windowvis);
  810.                 SectRgn(GetGrayRgn, rgn, rgn);
  811.                 r := rgn^^.rgnBBox;
  812.                 DisposeRgn(rgn);
  813.                 dummy := SectRect(r, windowvis, r);
  814.                 if (longint(r.topLeft) = longint(windowvis.topLeft)) & (longint(r.botRight) = longint(windowvis.botRight)) then begin
  815.                     with windowpos do begin
  816.                         MoveWindow(window, left, top + titlebar_hight, true);
  817.                         SizeWindow(window, right - left, bottom - top - titlebar_hight, true);
  818.                     end;
  819.                 end;
  820.                 if zoomed then begin
  821.                     Zoom(true, false);
  822.                 end else begin
  823.                     Resize;
  824.                 end;
  825.             end;
  826.             HUnlock(h);
  827.         end else
  828.             wasvisible := true;
  829.     end;
  830.  
  831.     procedure WObject.DoClose;
  832.     begin
  833.         if close_hides_window then begin
  834.             HideWindow(window);
  835.         end else begin
  836.             Destroy;
  837.         end;
  838.     end;
  839.  
  840.     procedure WObject.DoContent (const er: EventRecord);
  841.     begin
  842. {$unused(er)}
  843.     end;
  844.  
  845.     procedure WObject.DoKey (const er:EventRecord; ch: char);
  846.     begin
  847. {$unused(er, ch)}
  848.         SysBeep(1);
  849.     end;
  850.  
  851.     procedure WObject.DoSpecialKey (const er:EventRecord; ch: char);
  852.         var
  853.             item: integer;
  854.     begin
  855.         item := -1;
  856.         case EventKeyCode( er ) of
  857.             undoKey: 
  858.                 item := EMundo;
  859.             cutKey: 
  860.                 item := EMcut;
  861.             copyKey: 
  862.                 item := EMcopy;
  863.             pasteKey: 
  864.                 item := EMpaste;
  865.             clearKey: 
  866.                 item := EMclear;
  867.             otherwise begin
  868.                 { do nothing }
  869.             end;
  870.         end;
  871.         if item <> -1 then begin
  872.             SetMenus;
  873.             if not GetIDItemEnable(M_Edit, 0) or not GetIDItemEnable(M_Edit, item) then begin
  874.                 item := -1;
  875.             end;
  876.         end;
  877.         if item = -1 then begin
  878. {            if not EventHasCommandKey( er ) then begin}
  879.                 DoKey(er, ch);
  880. {            end;}
  881.         end else begin
  882.             DoFMenu(M_Edit, item);
  883.         end;
  884.     end;
  885.  
  886.     procedure WObject.DoAutoKey (const er:EventRecord; ch: char);
  887.     begin
  888.         DoKey(er, ch);
  889.     end;
  890.  
  891.     procedure WObject.DoDrag (where: Point);
  892.         var
  893.             temprect: Rect;
  894.     begin
  895.         SetPort(window);
  896.         temprect := GetGrayRgn^^.rgnBBox;
  897.         DragWindow(window, where, temprect);
  898.     end;
  899.  
  900.     procedure WObject.DoGrow (where: Point);
  901.         var
  902.             mypt: Point;
  903.             oldrect: Rect;
  904.             mResult: longint;
  905.             tempRect: Rect;
  906.     begin
  907.         SetPort(window);
  908.         mypt := where;
  909.         GlobalToLocal(mypt);
  910.         GetWindowPortRect(window, oldrect);
  911.         mResult := GrowWindow(window, where, growRect);
  912.         SizeWindow(window, LoWord(mResult), HiWord(mResult), TRUE);
  913.         SetRect(tempRect, 0, mypt.v - 15, mypt.h + 15, mypt.v + 15);
  914.         EraseRect(tempRect);
  915.         InvalRect(tempRect);
  916.         SetRect(tempRect, mypt.h - 15, 0, mypt.h + 15, mypt.v + 15);
  917.         EraseRect(tempRect);
  918.         InvalRect(tempRect);
  919.         zoomed := false;
  920.         Resize;
  921.     end;
  922.  
  923.     procedure WObject.Zoom (zoomout: boolean; fullscreen: boolean);
  924.         var
  925.             zoompt: Point;
  926.     begin
  927.         if fullscreen then begin
  928.             SetPt(zoompt, 30000, 30000);
  929.         end else begin
  930.             zoompt := zoomSize;
  931.         end;
  932.         zoompt.h := Max(zoompt.h, growRect.left);
  933.         zoompt.v := Max(zoompt.v, growRect.top);
  934.         ZoomTheWindow(window, zoomout, zoompt, unzoomed);
  935.         Resize;
  936.         zoomed := zoomout;
  937.     end;
  938.  
  939.     procedure WObject.DoZoom (where: Point; code: integer);
  940.     begin
  941.         SetPort(window);
  942.         if TrackBox(window, where, code) then begin
  943.             Zoom(not zoomed, last_event_had_option);
  944.         end;
  945.     end;
  946.  
  947.     procedure WObject.InitialZoom (h, v: integer);
  948.         var
  949.             old: Point;
  950.     begin
  951.         Resize;
  952.         old := zoomSize;
  953.         if h <> 0 then begin
  954.             zoomSize.h := h;
  955.         end;
  956.         if v <> 0 then begin
  957.             zoomSize.v := v;
  958.         end;
  959.         Zoom(true, false);
  960.         zoomSize := old;
  961.         zoomed := false;
  962.         GetWindowRect(window, unzoomed);
  963.     end;
  964.  
  965.     procedure WObject.DoGoAway (where: Point);
  966.     begin
  967.         if TrackGoAway(window, where) then begin
  968.             DoCloseAll(last_event_had_option);
  969.         end;
  970.     end;
  971.  
  972.     procedure WObject.DoUpdate;
  973.     begin
  974.         BeginUpdate(window);
  975.         Draw;
  976.         EndUpdate(window);
  977.     end;
  978.  
  979.     procedure WObject.TextChanged;
  980.     begin
  981.     end;
  982.  
  983.     procedure WObject.DoMouseMoved (where: Point);
  984.     begin
  985. {$unused(where)}
  986.     end;
  987.  
  988.     procedure WObject.DrawGrow;
  989.     begin
  990.         DrawGrowIcon(window);
  991.     end;
  992.  
  993.     procedure WObject.DoActivateDeactivate (activate: boolean);
  994.     begin
  995.         Assert(window <> nil);
  996.         is_active := activate and WindowPeek(window)^.visible;
  997.         if is_active then begin
  998.             SelectWindow(window);
  999.         end;
  1000.         if draw_grow_icon then begin
  1001.             DrawGrow;
  1002.         end;
  1003.     end;
  1004.  
  1005.     procedure WObject.Resize;
  1006.     begin
  1007.         if draw_grow_icon then begin
  1008.             DrawGrow;
  1009.         end;
  1010.     end;
  1011.  
  1012.     procedure WObject.Draw;
  1013.     begin
  1014.         if draw_grow_icon then begin
  1015.             DrawGrow;
  1016.         end;
  1017.     end;
  1018.  
  1019.     function WObject.DoIsDialogEvent (const er: EventRecord): boolean;
  1020.     begin
  1021.         if (( er.what = keyDown ) | ( er.what = autoKey )) & ( EventKeyCode( er ) in [undoKey, cutKey, copyKey, pasteKey, clearKey] ) then begin
  1022.             DoIsDialogEvent := false;
  1023.         end else begin
  1024.             DoIsDialogEvent := IsDialogEvent(er);
  1025.         end;
  1026.     end;
  1027.  
  1028.     function WObject.DoDialogSelect (const er: EventRecord; var dlg: DialogPtr; var item: integer): boolean;
  1029.     begin
  1030.         DoDialogSelect := DialogSelect(er, dlg, item);
  1031.     end;
  1032.  
  1033.     procedure WObject.DoIdle;
  1034.     begin
  1035.     end;
  1036.     
  1037.     procedure WObject.DoIdleAlways;
  1038.     begin
  1039.     end;
  1040.  
  1041.     procedure WObject.DoPopupTitle (choice: integer);
  1042.     begin
  1043. {$unused(choice)}
  1044.     end;
  1045.  
  1046.     function WObject.CheckPopupTitle (where: Point): boolean;
  1047.         var
  1048.             result: longint;
  1049.             center, width: integer;
  1050.             saved: SavedWindowInfo;
  1051.             title: Str255;
  1052.             base: Point;
  1053.     begin
  1054.         CheckPopupTitle := false;
  1055.         if popup_title_menu <> nil then begin
  1056.             EnterWindow(window, MFT_System0, [], saved);
  1057.             GlobalToLocal(where);
  1058.             GetWTitle(window, title);
  1059.             center := (window^.portRect.right + window^.portRect.left) div 2;
  1060.             width := StringWidth(title);
  1061.             base.h := center - width div 2 - 14;
  1062.             base.v := -17;
  1063.             if (where.v < 0) & (base.h <= where.h) & (where.h <= center + width div 2 + 5) then begin
  1064.                 CheckPopupTitle := true;
  1065.                 InsertMenu(popup_title_menu, -1);
  1066.                 LocalToGlobal(base);
  1067.                 CheckItem(popup_title_menu, 1, true);
  1068.                 result := PopUpMenuSelect(popup_title_menu, base.v, base.h, 1);
  1069.                 CheckItem(popup_title_menu, 1, false);
  1070.                 DeleteMenu(popup_title_menu^^.menuID);
  1071.                 if (HiWord(result) <> 0) and (LoWord(result) <> 1) then begin
  1072.                     DoPopupTitle(LoWord(result));
  1073. {DrawPopUp(dialog, item);}
  1074.                 end;
  1075.             end;
  1076.             ExitWindow(saved);
  1077.         end;
  1078.     end;
  1079.  
  1080.     function WObject.DoMainClick (const er: EventRecord; wp: WindowPtr; code: integer): boolean;
  1081.         var
  1082.             b: boolean;
  1083.             mResult: longint;
  1084.             needsselect: boolean;
  1085.     begin
  1086.         b := false;
  1087.         needsselect := (wp <> nil) & (wp <> FrontWindow);
  1088.         if needsselect & not (code in [inDrag, inContent]) then begin
  1089.             SelectWindow(wp);
  1090.         end;
  1091.         case code of
  1092.             inMenuBar:  begin
  1093.                 SetMenus;
  1094.                 mResult := MenuSelect(er.where);
  1095.                 if mResult <> 0 then begin
  1096.                     DoFMenu(HiWord(mResult), LoWord(mResult));
  1097.                 end;
  1098.                 if not quitNow then begin
  1099.                     HiliteMenu(0);
  1100.                 end;
  1101.             end;
  1102.             inDrag:  begin
  1103.                 if needsselect | not last_event_had_command | not CheckPopupTitle(er.where) then begin
  1104.                     if needsselect and not last_event_had_command then begin
  1105.                         SelectWindow(wp);
  1106.                     end;
  1107.                     DoDrag(er.where);
  1108.                 end;
  1109.             end;
  1110.             inGrow: 
  1111.                 DoGrow(er.where);
  1112.             inZoomIn, inZoomOut: 
  1113.                 DoZoom(er.where, code);
  1114.             inGoAway: 
  1115.                 DoGoAway(er.where);
  1116.             inContent:  begin
  1117.                 if needsselect then begin
  1118.                     SelectWindow(wp);
  1119.                 end;
  1120.                 DoContent(er);
  1121.             end;
  1122.             inSysWindow: 
  1123.                 SystemClick(er, window);
  1124.             otherwise begin
  1125.                 b := true;
  1126.             end;
  1127.         end;
  1128.         DoMainClick := b;
  1129.     end;
  1130.  
  1131.     function WObject.HandleSimpleEvents (var er: EventRecord): boolean;
  1132.         var
  1133.             b: boolean;
  1134.             ch: char;
  1135.             mResult: longint;
  1136.             code: integer;
  1137.             wp: WindowPtr;
  1138.     begin
  1139.         b := false;
  1140.         case er.what of
  1141.             mouseDown:  begin
  1142.                 code := FindWindow(er.where, wp);
  1143.                 if wp = nil then begin
  1144.                     wp := FrontWindow;
  1145.                 end;
  1146.                 b := GetWObject(wp).DoMainClick(er, wp, code);
  1147.             end;
  1148.  
  1149.             keyDown:  begin
  1150.                 ch := EventChar( er );
  1151.                 mResult := 0;
  1152.                 if last_event_had_command then begin
  1153.                     SetMenus;
  1154.                     mResult := DoMenuKey(er, ch);
  1155.                 end;
  1156.                 if mResult <> 0 then begin
  1157.                     DoFMenu(HiWord(mResult), LoWord(mResult));
  1158.                 end else begin
  1159.                     DoSpecialKey(er, ch);
  1160.                 end;
  1161.             end;
  1162.  
  1163.             autoKey: 
  1164.                 DoAutoKey(er, EventChar( er ) );
  1165.  
  1166.             updateEvt: 
  1167.                 GetWObject(WindowPtr(er.message)).DoUpdate;
  1168.  
  1169.             activateEvt: 
  1170.                 GetWObject(WindowPtr(er.message)).DoActivateDeactivate( EventHasActivate( er ) );
  1171.  
  1172.             kOSEvent: 
  1173.                 if EventIsSuspendResume( er ) then begin
  1174.                     DoSuspendResume( EventHasResume( er ) );
  1175.                 end else if EventIsMouseMoved( er ) then begin
  1176.                     DoMouseMoved(er.where);
  1177.                 end else begin
  1178.                     b := true;
  1179.                 end;
  1180.  
  1181.             kHighLevelEvent: 
  1182.                 DoHighLevel(er);
  1183.  
  1184.             diskEvt: 
  1185.                 DoDiskEvent(er.message);
  1186.  
  1187.             otherwise begin
  1188.                 b := true;
  1189.             end;
  1190.         end;
  1191.         HandleSimpleEvents := b;
  1192.     end;
  1193.  
  1194.     function WObject.HandleEvents (var er: EventRecord): boolean;
  1195.         var
  1196.             b: boolean;
  1197.             dlg: DialogPtr;
  1198.             item: integer;
  1199.             dlgsel:boolean;
  1200.     begin
  1201.         last_event := er;
  1202.         last_event_time := er.when;
  1203.         last_event_had_option := EventHasOptionKey( er );
  1204.         last_event_had_command := EventHasCommandKey( er );
  1205.         last_event_had_shift := EventHasShiftKey( er );
  1206.         last_event_had_control := EventHasControlKey( er );
  1207.         DoIdle;
  1208.         b := true;
  1209.         if DoIsDialogEvent(er) then begin
  1210.             dlgsel:=DoDialogSelect(er, dlg, item);
  1211.             if dlgsel then begin
  1212.                 GetDObject(dlg).DoItemWhere(er, item);
  1213.                 b := false;
  1214.             end;
  1215.         end;
  1216.         if b then begin
  1217.             b := HandleSimpleEvents(er);
  1218.         end;
  1219.         HandleEvents := b;
  1220.     end;
  1221.  
  1222.     procedure DObject.CreateBehind (id: integer; behind: WindowPtr);
  1223.         var
  1224.             wp: myDialogPtr;
  1225.             junk: OSErr;
  1226.     begin
  1227.         disable_edit_menu := false;
  1228.         junk := MNewPtr( wp, SizeOf(myDialogRecord) );
  1229.         wp^.magic := OOMagic;
  1230.         window := GetNewDialog(id, Ptr(wp), behind);
  1231.         Assert( window <> nil );
  1232.         ok_item := 0;
  1233.         cancel_item := 0;
  1234.         outline_item := 0;
  1235.         handle_shift_tab := true;
  1236.         text_return := false;
  1237.         support_edittext_draging_send := true;
  1238.         support_edittext_draging_receive := true;
  1239.         JointCreate(id);
  1240.     end;
  1241.  
  1242.     procedure DObject.Create (id: integer);
  1243.     begin
  1244.         CreateBehind(id, window_at_front);
  1245.     end;
  1246.  
  1247.     procedure DObject.Destroy;
  1248.     begin
  1249.         if (window <> nil) & (GetWType(window) <> WT_NotMine) then begin
  1250.             myDialogPtr(window)^.magic := BadOOMagic;
  1251.             DisposeDialog(window);
  1252.             if onlyone <> nil then begin
  1253.                 onlyone^ := nil;
  1254.             end;
  1255.             dispose(self);
  1256.         end;
  1257.     end;
  1258.  
  1259.     procedure DObject.DrawOutline( foreground: boolean );
  1260.     begin
  1261.         OutlineDefault1ForeBackground( window, outline_item, foreground );
  1262.     end;
  1263.  
  1264.     procedure DObject.SetOOOutline (def_item, user_item: integer);
  1265.     begin
  1266.         ok_item := def_item;
  1267.         outline_item := user_item;
  1268.         SetUpDefaultOutline(window,ok_item, outline_item, false);
  1269.         HandleUserItem( outline_item );
  1270.     end;
  1271.  
  1272.     procedure DObject.DrawUserItem( item: integer );
  1273.     begin
  1274. {$unused(item)}
  1275.         if (outline_item > 0) & (item = outline_item) then begin
  1276.             DrawOutline( InForeground );
  1277.         end else begin
  1278.             Assert( false );
  1279.         end;
  1280.     end;
  1281.  
  1282.     procedure DrawUserItem( window: DialogPtr; item: integer );
  1283.     begin
  1284.         GetDObject( window ).DrawUserItem( item );
  1285.     end;
  1286.     
  1287.     procedure DObject.HandleUserItem( item: integer );
  1288.     begin
  1289.         SetUserItemProc( window, item, dDrawUserItemProc );
  1290.     end;
  1291.     
  1292.     procedure DObject.HandleAllUserItems;
  1293.         var
  1294.             item: integer;
  1295.             kind: integer;
  1296.     begin
  1297.         for item := 1 to CountDItems( window ) do begin
  1298.             GetDItemKind( window, item, kind );
  1299.             if band(kind,GoodBNOT(itemDisable)) = userItem then begin
  1300.                 HandleUserItem( item );
  1301.             end;
  1302.         end;
  1303.     end;
  1304.                 
  1305.     procedure DObject.DoActivateDeactivate (activate: boolean);
  1306.     begin
  1307.         inherited DoActivateDeactivate(activate);
  1308.         if outline_item > 0 then begin
  1309.             DrawOutline( activate );
  1310.         end;
  1311.     end;
  1312.  
  1313.     procedure DObject.DoOK (const er: EventRecord; ch: char);
  1314.     begin
  1315.         if ok_item = 0 then begin
  1316.             DoKey(er, ch);
  1317.         end else begin
  1318.             if GetDCtlEnable(window, ok_item) then begin
  1319.                 FlashDItem(window, ok_item);
  1320.                 DoItem(ok_item);
  1321.             end;
  1322.         end;
  1323.     end;
  1324.  
  1325.     procedure DObject.DoCancel (const er: EventRecord; ch: char);
  1326.     begin
  1327.         if cancel_item = 0 then begin
  1328.             DoKey(er, ch);
  1329.         end else begin
  1330.             FlashDItem(window, cancel_item);
  1331.             DoItem(cancel_item);
  1332.         end;
  1333.     end;
  1334.  
  1335.     procedure DObject.DoItem (item: integer);
  1336.     begin
  1337. {$unused(item)}
  1338.     end;
  1339.  
  1340.     procedure DObject.DoItemWhere (const er: EventRecord; item: integer);
  1341.     begin
  1342. {$unused(er)}
  1343.         DoItem(item);
  1344.     end;
  1345.  
  1346.     function DObject.HandleEvents (var er: EventRecord): boolean;
  1347.         var
  1348.             b: boolean;
  1349.             ch: char;
  1350.     begin
  1351.         b := true;
  1352.         if EventIsKeyDown( er ) then begin
  1353.             b := false;
  1354.             ch := EventChar( er );
  1355.             if ((ch <> cr) | not text_return) & EventHasOK( er ) then begin
  1356.                 DoOK(er, ch);
  1357.             end else if EventHasCancel( er ) then begin
  1358.                 DoCancel(er, ch);
  1359.             end else if (ch = tab) and EventHasShiftKey( er ) then begin
  1360.                 if handle_shift_tab then begin
  1361.                     ShiftTab(window);
  1362.                 end else begin
  1363.                     b := true;
  1364.                 end;
  1365.             end else begin
  1366.                 b := true;
  1367.             end;
  1368.         end;
  1369.         if b then begin
  1370.             b := inherited HandleEvents(er);
  1371.         end;
  1372.         HandleEvents := b;
  1373.     end;
  1374.  
  1375.     procedure DObject.SetEditMenuItem (item: integer);
  1376.     begin
  1377.         if is_default_object | disable_edit_menu | (SelectedTextItem(window) <= 0) then begin
  1378.             SetIDItemEnable(M_Edit, item, false);
  1379.         end else begin
  1380.             TESetEditMenuItem(DialogPeek(window)^.textH, false, 250, item);
  1381.         end;
  1382.     end;
  1383.  
  1384.     function DObject.EditMenuEnabled: boolean;
  1385.     begin
  1386.         if is_default_object | disable_edit_menu | (SelectedTextItem(window) <= 0) then begin
  1387.             EditMenuEnabled := false;
  1388.         end else begin
  1389.             EditMenuEnabled := TEEditMenuEnabled(DialogPeek(window)^.textH, false, 250);
  1390.         end;
  1391.     end;
  1392.  
  1393.     procedure DObject.DoDialogCut;
  1394.     begin
  1395.         DialogCut( window );
  1396.     end;
  1397.     
  1398.     procedure DObject.DoDialogCopy;
  1399.     begin
  1400.         DialogCopy( window );
  1401.     end;
  1402.     
  1403.     procedure DObject.DoDialogPaste;
  1404.     begin
  1405.         DialogPaste( window );
  1406.     end;
  1407.     
  1408.     procedure DObject.DoDialogDelete;
  1409.     begin
  1410.         DialogDelete( window );
  1411.     end;
  1412.     
  1413.     procedure DObject.DoEditMenu (item: integer);
  1414.         var
  1415.             loe: longint;
  1416.             oe: OSErr;
  1417.     begin
  1418.         case item of
  1419.             EMundo: 
  1420.                 ;
  1421.             EMcut:  begin
  1422.                 DoDialogCut;
  1423.                 loe := ZeroScrap;
  1424.                 oe := TEToScrap;
  1425.                 TextChanged;
  1426.             end;
  1427.             EMcopy:  begin
  1428.                 DoDialogCopy;
  1429.                 loe := ZeroScrap;
  1430.                 oe := TEToScrap;
  1431.             end;
  1432.             EMpaste:  begin
  1433.                 oe := TEFromScrap;
  1434.                 DoDialogPaste;
  1435.                 TextChanged;
  1436.             end;
  1437.             EMclear:  begin
  1438.                 DoDialogDelete;
  1439.                 TextChanged;
  1440.             end;
  1441.             EMselectall:  begin
  1442.                 if (SelectedTextItem(window) > 0) then begin
  1443.                     SelectDialogItemText(window, SelectedTextItem(window), 0, maxInt);
  1444.                 end;
  1445.             end;
  1446.             otherwise begin
  1447.                 { do nothing }
  1448.             end;
  1449.         end;
  1450.     end;
  1451.  
  1452.     function DObject.GetAESelection (var reply: AppleEvent): OSErr;
  1453.         var
  1454.             err: OSErr;
  1455.     begin
  1456.         if not is_default_object & (SelectedTextItem(window) > 0) then begin
  1457.             err := PutTESelectionToAERecord(reply, keyDirectObject, DialogPeek(window)^.textH);
  1458.         end else begin
  1459.             err := errAENoUserSelection;
  1460.         end;
  1461.         GetAESelection := err;
  1462.     end;
  1463.  
  1464.     function DObject.DoIsDialogEvent (const er: EventRecord): boolean;
  1465.         var
  1466.             wp: WindowPtr;
  1467.             doit: Boolean;
  1468.             curitem, clickitem: integer;
  1469.             localwhere: Point;
  1470.             wasdragged, wastrashed: Boolean;
  1471.     begin
  1472.         doit := true;
  1473.         if EventIsKeyDown( er ) and EventHasCommandKey( er ) then begin
  1474.             doit := false; { Stop system 7 from doing the edit menu as well }
  1475.         end;
  1476.         if doit & support_edittext_draging_send & (er.what=mouseDown) & (FindWindow(er.where, wp) = inContent) & (wp = window) then begin
  1477.             curitem := SelectedTextItem( window );
  1478.             if curitem > 0 then begin
  1479.                 SetPort( window );
  1480.                 localwhere := er.where;
  1481.                 GlobalToLocal( localwhere );
  1482.                 clickitem := FindDialogItem( window, localwhere ) + 1; { GlobalToLocal? }
  1483.                 if (clickitem = curitem) & PtInTEHiliteRgn( localwhere, DialogPeek(window)^.textH ) then begin
  1484.                     if (DragText( er, localwhere, DialogPeek(window)^.textH, false, wasdragged, wastrashed ) = noErr) & wasdragged then begin
  1485.                         if wastrashed then begin
  1486.                             DoDialogDelete;
  1487.                         end;
  1488.                         doit := false;
  1489.                     end;
  1490.                 end;
  1491.             end;
  1492.         end;
  1493.         if doit then begin
  1494.             doit := inherited DoIsDialogEvent(er);
  1495.         end;
  1496.         DoIsDialogEvent := doit;
  1497.     end;
  1498.  
  1499.     var
  1500.         drop_on_field_index: integer;
  1501.         drop_on_field_location: integer;
  1502.     
  1503.     function DObject.MyTrackingEnterWindow( dragref: DragReference ): Boolean;
  1504.     begin
  1505.         if support_edittext_draging_receive then begin
  1506.             MyTrackingEnterWindow := IsDragTypeAvailable( dragref, 'TEXT' );
  1507.         end else begin
  1508.             MyTrackingEnterWindow := false;
  1509.         end;
  1510.     end;
  1511.     
  1512.     procedure DObject.MyTrackingLeaveWindow( dragref: DragReference );
  1513.     begin
  1514. {$unused(dragref)}
  1515.     end;
  1516.  
  1517.     procedure DObject.MyTrackingInWindow( dragref: DragReference; localwhere: Point; var new_drag_hilited: Boolean; new_drag_hilite_rgn, new_drag_invert_rgn: RgnHandle );
  1518.         var
  1519.             item, start, fin: integer;
  1520.             cur_modifiers, mousedown_modifiers, mouseup_modifiers: integer;
  1521.             attributes: DragAttributes;
  1522.             docopy: boolean;
  1523.             junk: OSStatus;
  1524.     begin
  1525. {$unused(dragref)}
  1526.         DialogGetTextDropInformation( window, localwhere, drop_on_field_index, drop_on_field_location, new_drag_hilite_rgn, new_drag_invert_rgn );
  1527.         new_drag_hilited := drop_on_field_index > 0;
  1528.         if new_drag_hilited then begin
  1529.             GetDialogTextSelection( window, item, start, fin );
  1530.             if drop_on_field_index = item then begin
  1531.                 junk := GetDragAttributes( dragref, attributes );
  1532.                 junk := GetDragModifiers( dragref, cur_modifiers, mousedown_modifiers, mouseup_modifiers );
  1533.                 docopy := (band(attributes, dragInsideSenderWindow) = 0) | (band(bor(mousedown_modifiers, cur_modifiers), optionKey) <> 0);
  1534.                 if docopy then begin
  1535.                     if (start < drop_on_field_location) & (drop_on_field_location < fin) then begin                        
  1536.                         new_drag_hilited := false;
  1537.                     end;
  1538.                 end else begin
  1539.                     if (start <= drop_on_field_location) & (drop_on_field_location <= fin) then begin                        
  1540.                         new_drag_hilited := false;
  1541.                     end;
  1542.                 end;
  1543.             end;
  1544.         end;
  1545.     end;
  1546.     
  1547.     procedure DObject.InsertTextAndSelect( field: integer; offset: integer; data: Str255 );
  1548.         var
  1549.             field_contents: Str255;
  1550.     begin
  1551.         GetItemText( window, field, field_contents );
  1552.         if length( field_contents ) + length( data ) > 255 then begin
  1553.             data := TPcopy( data, 1, 255-length( field_contents ) );
  1554.         end;
  1555.         MidAssignP( field_contents, offset + 1, 0, data );
  1556.         SetItemText( window, field, field_contents );
  1557.         SelectDialogItemText( window, field, offset, offset + length(data) );
  1558.     end;
  1559.     
  1560.     function DObject.ReceiveHandler(dragref: DragReference): OSErr;
  1561.         var
  1562.             err, junk: OSErr;
  1563.             drag_contents: Str255;
  1564.             docopy: Boolean;
  1565.             attributes: DragAttributes;
  1566.             in_sender_window: Boolean;
  1567.             cur_modifiers, mousedown_modifiers, mouseup_modifiers: integer;
  1568.             dragdata: Handle;
  1569.             selStart, selEnd: integer;
  1570.     begin
  1571.         TrackingRemoveHiliting( dragref );
  1572.         if drop_on_field_index > 0 then begin
  1573.             junk := GetDragAttributes(dragref, attributes);
  1574.             junk := GetDragModifiers(dragref, cur_modifiers, mousedown_modifiers, mouseup_modifiers );
  1575.  
  1576.             in_sender_window := (band(attributes, dragInsideSenderWindow) <> 0);
  1577.             docopy := not in_sender_window | (band(bor(mousedown_modifiers, mouseup_modifiers), optionKey) <> 0);
  1578.  
  1579. {            drop_on_field_finish := drop_on_field_location;}
  1580.             
  1581.             junk := MNewHandle( dragdata, 0 );
  1582.             err := GetTextDragData( dragref, dragdata );
  1583.             if err = noErr then begin
  1584.                 HandleToString( dragdata, drag_contents );
  1585.                 if docopy then begin
  1586.                     InsertTextAndSelect( drop_on_field_index, drop_on_field_location, drag_contents );
  1587.                 end else if SelectedTextItem( window ) <> drop_on_field_index then begin
  1588.                     DoDialogDelete;
  1589.                     InsertTextAndSelect( drop_on_field_index, drop_on_field_location, drag_contents );
  1590.                 end else begin
  1591.                     GetDialogTextSelection( window, drop_on_field_index, selStart, selEnd );
  1592.                     DoDialogDelete;
  1593.                     if (selStart <= drop_on_field_location) & (drop_on_field_location <= selEnd) then begin
  1594.                         { should never happen except on edge of boundary }
  1595.                         drop_on_field_location := selStart;
  1596.                     end else if drop_on_field_location > selEnd then begin
  1597.                         drop_on_field_location := drop_on_field_location - (selEnd-selStart);
  1598.                     end;
  1599.                     InsertTextAndSelect( drop_on_field_index, drop_on_field_location, drag_contents );
  1600.                 end;
  1601.             end;
  1602.             MDisposeHandle( dragdata );
  1603.         end;
  1604.         ReceiveHandler := err;
  1605.     end;
  1606.  
  1607.     procedure DObject.CalculateRegion (var rgn: RgnHandle);
  1608.         var
  1609.             item,k:integer;
  1610.             pt:Point;
  1611.     begin
  1612.         rgn := nil;
  1613.         item:=0;        
  1614.         if (window<>nil) then begin
  1615.             SetPort(window);
  1616.             GetMouse(pt);
  1617.             item:=FindDialogItem(window,pt)+1;
  1618.             if item>0 then begin
  1619.                 GetDItemKind(window,item,k);
  1620.                 if k<>editText then begin
  1621.                     item:=0;
  1622.                 end;
  1623.             end;
  1624.         end;
  1625.         if item>0 then begin
  1626.             CursorSetIBeam;
  1627.         end else begin
  1628.             CursorSetArrow;
  1629.         end;
  1630.     end;
  1631.  
  1632.     function HasDragLib:boolean;
  1633.     begin
  1634. {$IFC GENERATINGPOWERPC}
  1635.         HasDragLib := longint(@InstallTrackingHandler) <> kUnresolvedCFragSymbolAddress;
  1636. {$ELSEC}
  1637.         HasDragLib := true;
  1638. {$ENDC}
  1639.     end;
  1640.  
  1641.     procedure IdleMainLoop;
  1642.         var
  1643.             fw,next: WindowPtr;
  1644.             obj: WObject;
  1645.     begin
  1646.         fw:=FrontWindowList;
  1647.         while fw<>nil do begin
  1648.             next := NextWindowList ( fw );
  1649.             obj := GetWObject(fw);
  1650.             if obj.timetoclose then begin
  1651.                 obj.DoClose;
  1652.             end else begin
  1653.                 obj.DoIdleAlways;
  1654.             end;
  1655.             fw:=next;
  1656.         end;
  1657.     end;
  1658.     
  1659.     function InitMainLoop(var msg: integer): OSStatus;
  1660.         var
  1661.             i: integer;
  1662.             dummy: boolean;
  1663.             dummy_er: EventRecord;
  1664.             junk: OSErr;
  1665.             err: OSErr;
  1666.             HandleCloseProc:UniversalProcPtr;
  1667.             gv: longint;
  1668.     begin
  1669. {$unused(msg)}
  1670.         AssertDidStartup( startup_check );
  1671.         has_DragManager := HasDragLib & (Gestalt(gestaltDragMgrAttr, gv) = noErr) & (BTST(gv, gestaltDragMgrPresent));
  1672.         gMyDragSendProc := NewDragSendDataProc(MyDragSend);
  1673.         dDrawUserItemProc := NewUserItemProc(DrawUserItem);
  1674.         for i := 1 to 5 do begin
  1675.             dummy := EventAvail(everyEvent, dummy_er);
  1676.         end;
  1677.         if has_DragManager then begin
  1678.             err := InstallTrackingHandler(NewDragTrackingHandlerProc(MyTrackingHandler), nil, nil);
  1679.             err := InstallReceiveHandler(NewDragReceiveHandlerProc(MyReceiveHandler), nil, nil);
  1680.         end;
  1681.         default_object.window := nil;
  1682.         default_object.window_id := bad_window_id;
  1683.         default_object.JointCreate(0);
  1684.         default_object.is_default_object := true;
  1685.         default_object.window_type := WT_NotMine;
  1686.         last_window_id := 1;
  1687.         edit_menu_always_enabled := false;
  1688.         if has_AppleEvents then begin
  1689.             HandleCloseProc:=NewAEEventHandlerProc(HandleClose);
  1690.             junk := AEInstallEventHandler(kAECoreSuite, kAEClose,HandleCloseProc , 0, false);
  1691.             junk := AEInstallEventHandler(kAECoreSuite, kAECloseAll,HandleCloseProc , 1, false);
  1692.         end;
  1693.         InitMainLoop := noErr;
  1694.     end;
  1695.  
  1696.     procedure FinishMainLoop;
  1697.     begin
  1698.         dispose(default_object);
  1699.     end;
  1700.  
  1701.     procedure ConfigureMainLoop (dobj: DObject);
  1702.     begin
  1703.         DidStartup( startup_check );
  1704.         StartupMainLoop;
  1705.         default_object := dobj;
  1706.     end;
  1707.     
  1708.     procedure StartupMainLoop;
  1709.     begin
  1710.         StartupCleverAlerts;
  1711.         StartupCursors;
  1712.         StartupDialogs;
  1713.         StartupFMenus;
  1714.         SetStartup(InitMainLoop, IdleMainLoop, 15, FinishMainLoop);
  1715.     end;
  1716.     
  1717. end.
  1718.